package main

import (
	"fmt"
)

//--------Task相关--------

// Task 任务类型，其中f字段存任务的函数
type Task struct {
	f func() error
}

// NewTask 创建Task实例
func NewTask(argFunc func() error) *Task {
	return &Task{
		f: argFunc,
	}
}

// Execute 调用Task实例中的任务函数
func (t *Task) Execute() {
	t.f()
}

//--------Pool协程池--------

// Pool 协程池类型
type Pool struct {
	EntryChannel chan *Task //暴露出来的外部队列
	JobChannel   chan *Task //内部任务队列
	MaxWorkNum   int        //最大worker数
}

// NewPool 实例化Pool
func NewPool(MaxWorkNum int) *Pool {
	return &Pool{
		EntryChannel: make(chan *Task),
		JobChannel:   make(chan *Task),
		MaxWorkNum:   MaxWorkNum,
	}
}

// worker 相当于创建一个消者
func (p *Pool) worker(ID int) {
	for task := range p.JobChannel {
		task.Execute() //
		fmt.Printf("worker ID:%v\n", ID)
	}
}

// run 启动协程池
func (p *Pool) run() {
	//1、运行maxWorkNum个的worker(消费者)
	for i := 0; i < p.MaxWorkNum; i++ {
		go p.worker(i)
	}
	//2、从入口EntryChannel取出任务，放入内部的JobChannel
	//（这部分可以实现更加复杂的逻辑，例如按照某种权重或规则取出任务，再放入JobChannel）
	for task := range p.EntryChannel {
		p.JobChannel <- task
	}
}

func main() {
	//创建任务
	t := NewTask(func() error {
		fmt.Println("运行任务")
		return nil
	})

	//创建协程池
	p := NewPool(4)

	//向协程池写入30个任务
	go func() {
		for i := 0; i < 30; i++ {
			p.EntryChannel <- t
		}
		defer close(p.JobChannel)
		defer close(p.EntryChannel)

	}()

	//运行协程池的任务
	p.run()

}
